#Include ../debug.ahk

; auto create nodes
;
;

; desc:  node structure of dobule_linked_list
class DListNode {
  __New(val) {
    this.val := val
    this.prev := ''
    this.next := ''
  }

  ; param: data of node
  ; ret:   DListNode
  ; desc:  get node
  static BuyNode(val) {
    return DListNode(val)
  }
}

; desc:  dobule linked list
class DList {
  __New() {
    this.head := ''
    this.cur := this.head
    this.size := 0
  }

  ; param: data
  ; ret:
  ; desc:  add child node
  Append(val) {
    node := DListNode(val)
    ; the first node
    if !this.head {
      this.head := node
      this.cur := node
    }
    else {
      this.cur.next := node ; connect
      node.prev := this.cur
      this.cur := node ; set cur
    }
    this.size += 1
  }

  ; param: 
  ; ret:   typeof(this.var)
  ; desc:  delete the lasted node
  PopBack() {
    if !this.head
      return
    data := this.cur.val ; save
    this.cur := this.cur.prev ; delete & connect
    this.cur.next := '' ; release
    this.size -= 1
    return data
  }

  ; param: 
  ; ret:   string
  ; desc:  traverse from the very beginning
  Traverse() {
    list := ''
    currentNode := this.head
    while IsObject(currentNode) {
      list .= currentNode.val '-'
      currentNode := currentNode.next
    }
    return list
  }

  ; param: 
  ; ret:   size of list
  ; desc:  return the length of this
  Length() {
    return this.size
  }
}

if A_LineFile == A_ScriptFullPath {
  ; init queue
  q := DList()

  ; test push
  q.d.Join('--push')
  q.Append('a')
  q.Append('b')
  q.Append('c')
  q.Append('d')

  q.d.Join('--traverse')
  q.d.Join(q.Traverse())

  ; test pop
  q.d.Join('--pop')
  q.PopBack()
  q.PopBack()
  q.PopBack()

  q.d.Join('--traverse')
  q.d.Join(q.Traverse())

  q.d.Join('--over')
  q.d.Join(q.Length())

  q.d.Log()
}